// Sustainalytics.ESGRayings.ManagedCuda.h

#pragma once

#include "..\Sustainalytics.ESGRatings.Cuda\include\cudaEsg.h"
#include "exceptions.h"

namespace Sustainalytics
{
	namespace ESGRatings
	{
		namespace ManagedCuda
		{
			using namespace System;
			using namespace Sustainalytics::ESGRatings;

			public ref class ESGContext :public Sustainalytics::ESGRatings::Primitives::IESGComputeContext
			{
			private:
				Primitives::BufferManager^ _bufferManager;
				bool _disposed = false;

				CudaESGException^ CreateManagedException(cudaEsg::operation_errors_t& error);
				String^ CreateString(const char * sourceString);

				cudaEsg::ComputeContextFactory* _factory;
				cudaEsg::ComputeContext* _context;
				Primitives::Statistics^ _memoryStatistics;
			

			public:

				ESGContext();

				virtual property Primitives::Statistics^ MemoryStatistics {
					Primitives::Statistics^ get() sealed {
						if (_context->memoryStatistics) {
							auto op_it = _context->memoryStatistics->operationsList->begin();
							for (; op_it != _context->memoryStatistics->operationsList->end(); op_it++)
							{
								_memoryStatistics->Add(gcnew Primitives::MemorySizing(CreateString((*op_it)->name.c_str()), (*op_it)->bytes));
							}
						}

						return _memoryStatistics;
					}
				};

				virtual cli::array<int>^ __clrcall CleanContext();

				virtual  Primitives::RatingsResult^ __clrcall Ratings(int setId, int universeId, int matrixId, Byte filter, array<int>^groupByHeads, bool computeIndicatorsRatings, bool returnAggregatedWeights, bool returnWeights, bool isDefaultWeightMatrix);

				virtual  Primitives::GovernanceRatingsResult^ __clrcall Ratings(int setId, int matrixId,bool includeWeightedScores, bool includeWeights);

				virtual void __clrcall SetCombinationModifiers(int id, int matrixInternalId, int weightsCount, array<float>^ weightData);

				virtual void __clrcall SetIssueWeights(int id, int matrixInternalId, int weightsCount, array<float>^ weightData);

				virtual int  __clrcall AddCompanySet( int companiesCount, int indicatorsCount, int clusterCount, array<byte>^ esgHeads, array<byte>^disjunctClustersHeads, int disjunctClustersCount, array<byte>^ disjunctClustersMap);

				virtual void __clrcall SetIndicators(int setId, int companiesCount, int indicatorsCount, array<float>^ indicatorScores);

				virtual void __clrcall AddMatrix(int setId, int matrixId, int weightsCount, array<float>^ weightsMatrix, int profilesCount, array<byte>^profilesFlags);

				virtual bool __clrcall DeleteMatrix(int setId, int matrixId);

				virtual void __clrcall AddUniverse(int setId, int universeId, int elementsCount, array<Byte>^ univers);

				virtual bool __clrcall DeleteReferenceUniverse(int setId, int universeId);

				virtual void __clrcall SetAttributes(int setId, int elementsCount, array<Byte>^ attributes);

				virtual void __clrcall SetCompanyScores(int setId, int companiesNo, array<float>^ scoresData, array<float>^ weightsData);

				virtual void __clrcall SetAttributes(int setId, int companiesCount, int attributesTypesCount, array<int>^ regionGroupArray, int regionGroupsCount, array<int>^ peerGroupArray, int peerGroupsCount);

				virtual bool __clrcall DeleteSet(int setId);

				~ESGContext();

				!ESGContext();
			};
		}
	}
}
